package com.heima.common.aliyun;

import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "aliyun")
public class GreenImageScan {

    private String accessKeyId;
    private String secret;
    private String scenes;

    //服务是否部署在vpc上
    public boolean isVPC = false;

    //文件上传token endpoint->token
    public Map<String, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData> tokenMap = new HashMap<>();

    //上传文件请求客户端
    public static OSS ossClient = null;

    public Map imageScan(byte[] bytes) throws Exception {
        Map<String, String> resultMap = new HashMap<>();
        ImageModerationResponse response = invokeFunction("green-cip.cn-shanghai.aliyuncs.com",bytes);
        try {
            // 自动路由。
            if (response != null) {
                //区域切换到cn-beijing。
                if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                    // 接入区域和地址请根据实际情况修改。
                    response = invokeFunction("green-cip.cn-beijing.aliyuncs.com",bytes);
                }
            }
            // 打印检测结果。
            if (response != null) {
                if (response.getStatusCode() == 200) {
                    ImageModerationResponseBody body = response.getBody();
                    // System.out.println("requestId=" + body.getRequestId());
                    // System.out.println("code=" + body.getCode());
                    // System.out.println("msg=" + body.getMsg());
                    if (body.getCode() == 200) {
                        ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData();
                        // System.out.println("dataId=" + data.getDataId());
                        List<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> results = data.getResult();
                        for (ImageModerationResponseBody.ImageModerationResponseBodyDataResult result : results) {
                            // System.out.println("label=" + result.getLabel());

                            System.out.println("confidence=" + result.getConfidence());
                            if (result.getLabel().equals("nonLabel") && result.getConfidence() == null){
                                resultMap.put("suggestion","pass");
                            }else {
                                resultMap.put("suggestion","block");
                                if (result.getConfidence() <= 50){ // 置信分(0~100)：
                                    resultMap.put("suggestion","review");
                                }
                                resultMap.put("labels",result.getLabel());

                            }
                        }
                    } else {
                        System.out.println("image moderation not success. code:" + body.getCode());
                    }
                } else {
                    System.out.println("response not success. status:" + response.getStatusCode());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultMap;
    }

    /**
     * 创建请求客户端
     * @return
     * @throws Exception
     */
    public Client createClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(secret);
        config.setEndpoint("green-cip.cn-hangzhou.aliyuncs.com");
        return new Client(config);
    }

    public void getOssClient(DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData, boolean isVPC) {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        if (isVPC) {
            ossClient = new OSSClientBuilder().build(tokenData.ossInternalEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        } else {
            ossClient = new OSSClientBuilder().build(tokenData.ossInternetEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        }
    }

    public static String uploadFile(byte[] bytes, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData) throws Exception {

        String objectName = tokenData.getFileNamePrefix() + UUID.randomUUID();
        PutObjectRequest putObjectRequest = new PutObjectRequest(tokenData.getBucketName(), objectName, new ByteArrayInputStream(bytes));
        ossClient.putObject(putObjectRequest);
        return objectName;
    }


    // 一个方法，方法的参数为一个byte[]和一个路径
    public  String saveFile(String url,byte[] data) {
        // 获取文件路径中的原始扩展名
        String extension = url.substring(url.lastIndexOf("."));
        // 生成一个不重复的文件名，使用UUID类
        String fileName = UUID.randomUUID().toString() + extension;
        // 指定一个本地磁盘的目录，你可以根据你的需要更改
        String directory = "D:\\code\\leadnews\\tmpImg\\";
        // 创建一个File对象，表示要保存的文件
        File file = new File(directory + fileName);
        try {
            // 创建一个FileOutputStream对象，用于将byte数组写入文件
            FileOutputStream fos = new FileOutputStream(file);
            // 将byte数组写入文件
            fos.write(data);
            // 关闭输出流
            fos.close();
            // 返回文件在磁盘上的路径
            return file.getAbsolutePath();
        } catch (IOException e) {
            // 如果发生异常，打印异常信息，并返回null
            e.printStackTrace();
            return null;
        }
    }

    public ImageModerationResponse invokeFunction(String endpoint,byte[] bytes) throws Exception {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        Client client = createClient();
        RuntimeOptions runtime = new RuntimeOptions();

        //本地文件的完整路径，例如D:\localPath\exampleFile.png。
        String bucketName = null;
        DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData uploadToken = tokenMap.get(endpoint);
        //获取文件上传token
        if (uploadToken == null || uploadToken.expiration <= System.currentTimeMillis() / 1000) {
            DescribeUploadTokenResponse tokenResponse = client.describeUploadToken();
            uploadToken = tokenResponse.getBody().getData();
            bucketName = uploadToken.getBucketName();
        }
        //上传文件请求客户端
        getOssClient(uploadToken, isVPC);

        //上传文件
        String objectName = uploadFile(bytes, uploadToken);

        // 检测参数构造。
        Map<String, String> serviceParameters = new HashMap<>();
        //文件上传信息
        serviceParameters.put("ossBucketName", bucketName);
        serviceParameters.put("ossObjectName", objectName);
        serviceParameters.put("dataId", UUID.randomUUID().toString());

        ImageModerationRequest request = new ImageModerationRequest();
        // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
        request.setService("baselineCheck");
        request.setServiceParameters(JSON.toJSONString(serviceParameters));

        ImageModerationResponse response = null;
        try {
            response = client.imageModerationWithOptions(request, runtime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        client = null;
        return response;
    }

}